;; JavaFX Script Mode - A GNU Emacs major mode for editing JavaFX Script
;; Copyright (c) 2008, 2009, Iparelan Solutions, LLC. All rights reserved.

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;; Author: Greg Mattes
;; Version: February 2009

; This is a quick hack for use when developing JavaFX Script mode. Call
; reload-javafx-script-mode after making a changes to
; javafx-script-mode.el. Make sure that the development version of
; javafx-script-mode.el appears in your load path before any other versions:
;
; (push "your-path-to-javafx-script-mode-repos" load-path)
;
; There's probably some built-in Emacs way to reload a mode while it is under
; development which makes this code unnecessary -- if you know of such
; functionality, please tell me about it!
;
; I bind the reload-javafx-script-mode function to a function key cord. I use C-S-f4
; because it was available in my key map, change it for your tastes:
;
; (global-set-key [C-S-f4] 'reload-javafx-script-mode)

(defun reload-javafx-script-mode ()
  "Reloads `javafx-script-mode'. See `reload-mode'"
  (interactive)
  (reload-mode 'javafx-script-mode))

(defun reload-mode (mode &optional default-mode)
  "Not a mode, but a function that reloads a mode. Unloads and
reloads MODE (a quoted symbol), ensuring that any buffers in MODE
are updated with the new version of MODE. Such buffers are
temporarily switched to DEFAULT-MODE (a quoted symbol). If
DEFAULT-MODE is omitted, `fundamental-mode' is used."
  (interactive)

  ; ensure we have the latest changes
  (save-some-buffers t)

  ; forcefully unload the old version of the mode
  (when (memq mode features)
    (unload-feature mode t))

  ; reload the mode with the new version
  (require mode)

  ; iterate over all buffers, first change modes to some default, then to the reloaded mode
  (save-excursion
    ; map over all buffers, reloading the new mode
    (mapcar

     ; reload mode for all buffers that had mode changed to the default mode, ignore nil entries
     '(lambda (b)
        (when b
          (set-buffer b)
          (funcall (symbol-function mode))))

     ; map over all buffers changing to default mode
     (mapcar

     ; change to default mode, produce a list with buffers that were in mode,
     ; nil is produced in the list for buffers not in mode
     '(lambda (b)
        (set-buffer b)
        (if (eq major-mode mode)
            (progn
              (if default-mode
                  (funcall (symbol-function default-mode))
                (fundamental-mode))
              b)
          nil))
     (buffer-list)))))

(provide 'reload)
